<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
		"http://www.w3.org/TR/html4/strict.dtd">
<html>
	<head>
		<title>robot Tree DnD Multi-parent Test</title>

		<style>
			@import "../../../../util/doh/robot/robot.css";
		</style>

		<script type="text/javascript" src="../../../../dojo/dojo.js"></script>

		<script type="text/javascript">
			require([
				"doh/runner", "dojo/robotx",
				"dojo/dnd/common", "dojo/dom", "dojo/dom-class", "dojo/keys", "dojo/query", "dojo/sniff",
				"dijit/tests/helpers", "./Tree_dnd", "dojo/domReady!"
			], function(doh, robot, dndCommon, dom, domClass, keys, query, has, helpers, dndHelpers){

				robot.initRobot('../test_Tree_DnD.html');

				dndHelpers.setup();

				doh.register("multi-parent tests", [
					{
						name: "add 'Fruits' as parent of vegetables",
						timeout: 10000,
						runTest: function(){
							var
								d = new doh.Deferred(),
								vegetablesTreeNode = dndHelpers.findTreeNodeByPath("collectionsTree", ["Vegetables (0)"]),	// the left tree
								fruitsTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits"]);	// right tree

							robot.mouseMoveAt("collectionsTree", 500, 1); // scroll source parent into view
							robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
							// Drag and Drop, *copying* in order to add a parent rather than change
							robot.keyDown(keys.copyKey, 500);
							if(has("mac")){
								// I can't get DOH robot to generate the mousePress event w/metaKey=true so
								// hack it
								robot.sequence(function(){
									realIsCopyKey = dndCommon.getCopyKeyState;
									dndCommon.getCopyKeyState = function(){ return true; }
								});
							}

							robot.mousePress({left: true}, 500);
							robot.mouseMoveAt("itemTree", 500, 500); // move to dest parent to scroll it into view
							robot.mouseMoveAt(fruitsTreeNode.labelNode, 0, 500);
							robot.mouseRelease({left: true}, 500);
							robot.keyUp(keys.copyKey, 500);
							if(has("mac")){
								// See if(has("mac")) above
								robot.sequence(function(){
									dndCommon.getCopyKeyState = realIsCopyKey;
								});
							}

							robot.sequence(d.getTestCallback(function(){
								// Check that Vegetables remains a child of Foods
								var children = dndHelpers.getNamesOfChildrenOfItem("Foods");
								doh.is(3, children.categories.length, "foods category child");
								doh.is("Fruits", children.categories[0]);
								doh.is("Vegetables", children.categories[1]);
								doh.is("Cereals", children.categories[2]);

								// Check that Vegetables added as child of Fruits
								var children2 = dndHelpers.getNamesOfChildrenOfItem("Fruits");
								doh.is(2, children2.categories.length, "foods category child");
								doh.is("Citrus", children2.categories[0]);
								doh.is("Vegetables", children2.categories[1]);

								// Check that new item *wasn't* created
								var items;
								robot.window.myStore.fetch({
									onComplete: function(i){ items = i; }
								});
								doh.is(6, items.length, "# of items in store");

								// Check that data store update was reflected in the tree
								doh.t(fruitsTreeNode.isExpanded, "drop caused the node to expand");
								var treeNodeChildren = fruitsTreeNode.getChildren();
								doh.is(2, treeNodeChildren.length, "2 TreeNode children");
								doh.is("Citrus", helpers.innerText(treeNodeChildren[0].labelNode));
								doh.is("Vegetables", helpers.innerText(treeNodeChildren[1].labelNode));
							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node

							return d;
						}
					},
					{
						name: "move Foods/Vegetables to Foods/Cereal/Vegetables",
						timeout: 10000,
						runTest: function(){
							var
								d = new doh.Deferred(),
								vegetablesTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Vegetables"]),
								cerealsTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Cereals"]);

							robot.window.scrollTo(0, 9000); // scroll to bottom to try and prevent the DnD code from autoscrolling

							// Drag and Drop
							robot.mouseMoveAt(vegetablesTreeNode.domNode, 500, 1);
							robot.mouseClick({left: true}, 500); // helps prevent screen jitter
							robot.mousePress({left: true}, 1000);
							robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 500, 0, 0); // move mouse slightly to trigger DnD
							robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100); // double move to allow for autoscrolling jitter
							robot.mouseMoveAt(cerealsTreeNode.domNode, 500, 100);
							robot.mouseRelease({left: true}, 500);

							robot.sequence(d.getTestCallback(function(){
								// Check that Vegetables remains a child of Fruits
								var children = dndHelpers.getNamesOfChildrenOfItem("Fruits");
								doh.is(2, children.categories.length, "fruits category child");
								doh.is("Citrus", children.categories[0]);
								doh.is("Vegetables", children.categories[1]);

								// Check that Vegetables added as child of Cereals
								children = dndHelpers.getNamesOfChildrenOfItem("Cereals");
								doh.is(1, children.categories.length, "cereals category child");
								doh.is("Vegetables", children.categories[0]);

								// Check that Vegetables no longer a child of Foods
								children = dndHelpers.getNamesOfChildrenOfItem("Foods");
								doh.is(2, children.categories.length, "foods category child");
								doh.is("Fruits", children.categories[0]);
								doh.is("Cereals", children.categories[1]);

								// Check that new item *wasn't* created
								var items;
								robot.window.myStore.fetch({
									onComplete: function(i){ items = i; }
								});
								doh.is(6, items.length, "# of items in store");
							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node

							return d;
						}
					},
					{
						name: "move Fruits/Vegetables to Fruits/Citrus",
						timeout: 10000,
						runTest: function(){
							var
								d = new doh.Deferred(),
								vegetablesTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits", "Vegetables"]),
								citrusTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits", "Citrus"]);

							// Drag and Drop
							robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 1);
							robot.mouseClick({left: true}, 500); // helps prevent screen jitter
							robot.mousePress({left: true}, 1000);
							robot.mouseMoveAt(vegetablesTreeNode.labelNode, 500, 500, 0, 0); // move mouse slightly to trigger DnD
							robot.mouseMoveAt(citrusTreeNode.labelNode, 0, 500);
							robot.mouseRelease({left: true}, 500);

							robot.sequence(d.getTestCallback(function(){
								// Check that Vegetables remains a child of Cereals
								var children = dndHelpers.getNamesOfChildrenOfItem("Cereals");
								doh.is(1, children.categories.length, "cereals category child");
								doh.is("Vegetables", children.categories[0]);

								// Check that Vegetables added as child of Citrus
								children = dndHelpers.getNamesOfChildrenOfItem("Citrus");
								doh.is(1, children.categories.length, "citrus category child");
								doh.is("Vegetables", children.categories[0]);
								doh.is(1, children.items.length, "citrus item child");
								doh.is("Orange", children.items[0]);

								// Check that Vegetables removed as child of Fruits
								children = dndHelpers.getNamesOfChildrenOfItem("Fruits");
								doh.is(1, children.categories.length, "fruits category child");
								doh.is("Citrus", children.categories[0]);

								// Check that new item *wasn't* created
								var items;
								robot.window.myStore.fetch({
									onComplete: function(i){ items = i; }
								});
								doh.is(6, items.length, "# of items in store");
							}), 1000);	// 1000ms to wait for 'Fruits' node to expand and show 'Apple' node

							return d;
						}
					}
				]);

				doh.register("external drop tests", [
					{
						name: "drop banana on fruits",
						timeout: 10000,
						runTest: function(){
							var
								d = new doh.Deferred(),
								fruitsTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits"]);	// right tree

							var node = dom.byId("1003", robot.doc);
							robot.mouseMoveAt(node.parentNode, 500, 1, 0, 0); // move to source parent node to help prevent DnD autoscrolling
							robot.mouseMoveAt(node, 500, 1); // move to source banana node
							robot.mousePress({left: true}, 500);
							robot.mouseMoveAt(node.parentNode, 500, 100); //  move just a little to start the DnD operation before scrolling
							robot.mouseMoveAt("itemTree", 500, 500); // go to target parent top to allow for better scrolling of the destination
							robot.mouseMoveAt(fruitsTreeNode.labelNode, 1000, 500);
							robot.mouseRelease({left: true}, 500);

							robot.sequence(d.getTestCallback(function(){

								var children = dndHelpers.getChildrenOfItem("Fruits");
								doh.is(1, children.items.length, "new item added");
								doh.is(1003, children.items[0].id, "id of new item came from dropped node");
								doh.is("Banana", children.items[0].name, "name of new item came from dropped node");

								robot.window.myStore.fetch({
									query: { name: "Banana" },
									queryOptions: { deep: true },
									onComplete: function(i){ items = i; }
								});
								doh.is(1, items.length, "1 banana item in store");
							}), 1000);

							return d;
						}
					},
					{
						name: "drop banana on cereal",
						timeout: 10000,
						runTest: function(){
							var
								d = new doh.Deferred(),
								cerealsTreeNode = dndHelpers.findTreeNodeByPath("itemTree", ["Cereals"]);					// right tree

							var node = dom.byId("1003", robot.doc);
							robot.mouseMoveAt(node.parentNode, 500, 1, 0, 0); // move to source parent node to help prevent DnD autoscrolling
							robot.mouseMoveAt(node, 500, 1); // move to source banana node
							robot.mousePress({left: true}, 500);
							robot.mouseMoveAt(node.parentNode, 500, 100); //  move just a little to start the DnD operation before scrolling
							robot.mouseMoveAt("itemTree", 500, 100); // go to target parent top to allow for better scrolling of the destination
							robot.mouseMoveAt(cerealsTreeNode.labelNode, 1000, 500);
							robot.mouseRelease({left: true}, 500);

							robot.sequence(d.getTestCallback(function(){

								var children = dndHelpers.getChildrenOfItem("Cereals");
								doh.is(1, children.items.length, "banana is child of cereals");
								doh.is(1003, children.items[0].id, "id of item came from dropped node");
								doh.is("Banana", children.items[0].name, "name of new item came from dropped node");

								var children2 = dndHelpers.getChildrenOfItem("Fruits");
								doh.is(1, children2.items.length, "banana still a child of fruits");
								doh.is(1003, children2.items[0].id, "id of new item came from dropped node");
								doh.is("Banana", children2.items[0].name, "name of new item came from dropped node");

								robot.window.myStore.fetch({
									query: { name: "Banana" },
									queryOptions: { deep: true },
									onComplete: function(i){ items = i; }
								});
								doh.is(1, items.length, "1 banana item in store (with 2 parents)");
							}), 1000);

							return d;
						}
					}
				]);

				doh.register("illegal drop", [
					// This tests dropping a node onto another node when both nodes represent the same item.
					{
						name: "try to drop Vegetables as child of Vegetables",
						timeout: 10000,
						runTest: function(){
							var
								d = new doh.Deferred(),
								drag = dndHelpers.findTreeNodeByPath("itemTree", ["Cereals", "Vegetables"]),
								aboveDrop = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits", "Citrus"]);
								drop = dndHelpers.findTreeNodeByPath("itemTree", ["Fruits", "Citrus", "Vegetables"]);

							doh.is(drop.item.id, drag.item.id, "both nodes point to same item");

							// Drag bottom vegetables node over Citrus
							robot.mouseMoveAt(drag.domNode, 500, 1);
							robot.mousePress({left: true}, 500);
							robot.mouseMoveAt(aboveDrop.labelNode, 0, 500);

							robot.sequence(d.getTestErrback(function(){
								var avatar = query(".dojoDndAvatar", robot.doc);
								doh.t(avatar && avatar[0], "avatar found");
								doh.t(domClass.contains(avatar[0], "dojoDndAvatarCanDrop"), "can drop");
							}), 500);

							// Now move it to over first Vegetables node.   Should be red icon indicating drop-unallowed
							robot.mouseMoveAt(drop.labelNode, 0, 500);
							robot.sequence(d.getTestErrback(function(){
								var avatar = query(".dojoDndAvatar", robot.doc);
								doh.t(avatar && avatar[0], "avatar found");
								doh.f(domClass.contains(avatar[0], "dojoDndAvatarCanDrop"), "can't drop");
							}), 500);

							// Try to drop anyway, and make sure Tree structure doesn't change
							robot.mouseRelease({left: true}, 500);
							robot.sequence(d.getTestCallback(function(){
								doh.is(0, drop.getChildren().length, "drop node has no children");
								doh.t(drag == dndHelpers.findTreeNodeByPath("itemTree", ["Cereals", "Vegetables"]),
										"drag node still in same place");
							}), 500);

							return d;
						}
					}
				]);

				doh.run();
			});
		</script>
	</head>
</html>
